﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WatiN.Core;
using WatiN.Core.DialogHandlers;
using WatiN.Core.Native.Windows;

namespace Util
{
    static class IEHelper
    {
        public static int CountText(this IE ie, string text, string selector = "body")
        {
            const string fmtstr = "($('{0}').text().match(/{1}/g) || []).length";
            var count = ie.Eval(string.Format(fmtstr, selector, text));
            return int.Parse(count);
        }

        public static void WaitUntil_AjaxRedirect(this IE ie, ConfirmDialogHandler confirmDialogHandler = null)
        {
            ie.Eval("$('div:contains(Sung)').remove()");
            if (confirmDialogHandler != null) {
                confirmDialogHandler.WaitUntilExists();
                confirmDialogHandler.OKButton.Click();
            }
            ie.WaitUntilContainsText("Sung");
        }

        public static void WaitAjax(this IE ie, int timeout = 5000)
        {
            for (int i = 0; i < timeout / 100; ++i) {
                System.Threading.Thread.Sleep(100);
                var s = ie.Eval("$.active");
                if (s == "0") break;
            }
        }

        public static void 링크누르고메시지확인(this IE ie, string 링크실렉터, string 확인메시지)
        {
            var alertDialogHandler = new AlertDialogHandler();
            ie.AddDialogHandler(alertDialogHandler);

            ie.Link(Find.BySelector(링크실렉터)).ClickNoWait();
            alertDialogHandler.WaitUntilExists(4);
            var msg = alertDialogHandler.Message;
            alertDialogHandler.OKButton.Click();
            Assert.IsTrue(msg.Contains(확인메시지));

            ie.RemoveDialogHandler(alertDialogHandler);
        }

        public static void 버튼누르고메시지확인(this IE ie, string 링크실렉터, string 확인메시지)
        {
            var alertDialogHandler = new AlertDialogHandler();
            ie.AddDialogHandler(alertDialogHandler);

            ie.Button(Find.BySelector(링크실렉터)).ClickNoWait();
            alertDialogHandler.WaitUntilExists(4);
            var msg = alertDialogHandler.Message;
            alertDialogHandler.OKButton.Click();
            Assert.IsTrue(msg.Contains(확인메시지));

            ie.RemoveDialogHandler(alertDialogHandler);
        }

        public static void 컨펌버튼누르기(this IE ie, string 버튼텍스트)
        {
            var confirmDialogHandler = new ConfirmDialogHandler();
            ie.AddDialogHandler(confirmDialogHandler);
            ie.Link(Find.ByText(버튼텍스트)).ClickNoWait();
            confirmDialogHandler.WaitUntilExists();
            confirmDialogHandler.OKButton.Click();
            ie.RemoveDialogHandler(confirmDialogHandler);
        }

        public static void 컨펌버튼누르고메시지확인(this IE ie, string 버튼텍스트, string 확인메시지)
        {
            var confirmDialogHandler = new ConfirmDialogHandler();
            ie.AddDialogHandler(confirmDialogHandler);
            var alertDialogHandler = new AlertDialogHandler();
            ie.AddDialogHandler(alertDialogHandler);

            ie.Link(Find.ByText(버튼텍스트)).ClickNoWait();
            confirmDialogHandler.WaitUntilExists();
            confirmDialogHandler.OKButton.Click();
            alertDialogHandler.WaitUntilExists(4);
            var msg = alertDialogHandler.Message;
            alertDialogHandler.OKButton.Click();
            Assert.IsTrue(msg.Contains(확인메시지));

            ie.RemoveDialogHandler(alertDialogHandler);
            ie.RemoveDialogHandler(confirmDialogHandler);
        }

        public static void 폼데이터입력(this IE ie, string[,] 데이터)
        {
            for (int i = 0; i < 데이터.GetLength(0); ++i) {
                var 필드명 = 데이터[i, 0];
                var 필드값 = 데이터[i, 1];
                var 태그 = ie.Eval(string.Format("$('[name={0}]').prop('tagName')", 필드명));
                if (태그 == "SELECT")
                    ie.SelectList(Find.ByName(필드명)).Select(필드값);
                else {
                    var 타입 = ie.Eval(string.Format("$('[name={0}]').attr('type')", 필드명)).ToUpper();
                    if (타입 == "RADIO")
                        ie.RadioButton(Find.ByName(필드명) && Find.ByValue(필드값)).Click();
                    else
                        ie.TextField(Find.ByName(필드명)).Value = 필드값;
                }
            }
        }

        public static void 폼데이터확인(this IE ie, string[,] 데이터)
        {
            for (int i = 0; i < 데이터.GetLength(0); ++i) {
                var 필드명 = 데이터[i, 0];
                var 필드값 = 데이터[i, 1];
                var 태그 = ie.Eval(string.Format("$('[name={0}]').prop('tagName')", 필드명));
                if (태그 == "SELECT")
                    Assert.AreEqual(ie.SelectList(Find.ByName(필드명)).SelectedItem, 필드값);
                else {
                    var 타입 = ie.Eval(string.Format("$('[name={0}]').attr('type')", 필드명)).ToUpper();
                    if (타입 == "RADIO")
                        Assert.IsTrue(ie.RadioButton(Find.ByName(필드명) && Find.ByValue(필드값)).Checked);
                    else
                        Assert.AreEqual(ie.TextField(Find.ByName(필드명)).Value, 필드값);
                }
            }
        }
       
        public static void UploadFile(this IE ie, string 버튼텍스트, string 파일경로)
        {
            ie.Link(Find.ByText(p => p.Contains(버튼텍스트))).Click();
            System.Threading.Thread.Sleep(1000);
            var upload = ie.Frames[0].FileUploads[0];
            upload.Set(파일경로);
        }

        public static void DownloadFile(this Browser browser)
        {
            // see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx)
            Window windowMain = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(browser.hWnd, 5));
            System.Windows.Automation.TreeWalker trw = new System.Windows.Automation.TreeWalker(System.Windows.Automation.Condition.TrueCondition);
            System.Windows.Automation.AutomationElement mainWindow = trw.GetParent(System.Windows.Automation.AutomationElement.FromHandle(browser.hWnd));

            Window windowDialog = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(windowMain.Hwnd, 5));
            // if doesn't work try to increase sleep interval or write your own waitUntill method
            Thread.Sleep(1000);
            windowDialog.SetActivate();
            System.Windows.Automation.AutomationElementCollection amc = System.Windows.Automation.AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition);

            foreach (System.Windows.Automation.AutomationElement element in amc) {
                // You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum
                if (element.Current.Name.Equals("저장")) {
                    // if doesn't work try to increase sleep interval or write your own waitUntil method
                    // WaitUntilButtonExsist(element,100);
                    Thread.Sleep(100);
                    System.Windows.Automation.AutomationPattern[] pats = element.GetSupportedPatterns();
                    // replace this foreach if you need 'Save as' with code bellow
                    foreach (System.Windows.Automation.AutomationPattern pat in pats) {
                        // '10000' button click event id 
                        if (pat.Id == 10000) {
                            System.Windows.Automation.InvokePattern click = (System.Windows.Automation.InvokePattern)element.GetCurrentPattern(pat);
                            click.Invoke();
                        }
                    }
                    break;
                }
            }
        }
    }
}
